﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WcfPOXCommunication
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true, ValidateMustUnderstand = false)]
    public class ServiceFacade: IServiceFacade
    {
        private IServiceInvoker ServiceInvoker { get; set; }

        private IRequestProcessor RequestProcessor { get; set; }

        private IResponseProcessor ResponseProcessor { get; set; }

        public ServiceFacade()
        {
            ServiceInvoker = new ServiceInvoker();
            RequestProcessor = new RequestProcessor();
            ResponseProcessor = new ResponseProcessor();
        }

        //TODO: code unit tests
        public Message HandleMessage(Message request)
        {
            if (!request.IsEmpty)
            {
                try
                {
                    var serviceRequest = request.GetBody<ServiceRequest>();
                    var specification = RequestProcessor.Decode(serviceRequest);

                    var instance = IoCFactory.Resolve(specification.ServiceType);
                    var result = specification.Method.Invoke(instance, specification.Parameters);
                    var response = ResponseProcessor.Encode(serviceRequest, result);
                    var message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, 
                        "HandleMessageResponse", response);
                    return message;
                }
                catch (Exception ex)
                {
                    return Message.CreateMessage(MessageVersion.Soap12, "HandleAllMessage",
                       new ServiceResponse
                       {
                           Success = false,
                           ErrorMessage = ex.Message,
                           FaultType = ex.GetType().FullName,
                           Result = null
                       });
                }
            }
            throw new FaultException("No request specification recieved.");
        }
    }
}